package com.wwf.filter.com.wwf.util;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

/**
 * tp计算方法
 */
public class TpCount {
    /**
     * 存当前yymd HH:mm （当前年月日十分范围内的调用耗时）
     */
    //private static ConcurrentHashMap<Long,TreeMap<Long, Long>> timeReginMap = new ConcurrentHashMap<Long,TreeMap<Long, Long>>();
    private static Map<String,ConcurrentHashMap<Long,TreeMap<Long, Long>>> timeReginMap = new HashMap<String,ConcurrentHashMap<Long,TreeMap<Long, Long>>>();

    //TreeMap<Long, Long> treeMap = new TreeMap<>(Comparator.naturalOrder());
    static {
        Executors.newSingleThreadScheduledExecutor().scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
                // System.out.println("sdsdsd");
                TpCount.reportTp();
            }
        },1,5, TimeUnit.SECONDS);
    }
    public static synchronized void  doTpCount(long spendTimems,String methodname) {
        ConcurrentHashMap<Long, TreeMap<Long, Long>> longTreeMapConcurrentHashMap = timeReginMap.get(methodname);
        if(longTreeMapConcurrentHashMap == null){
            longTreeMapConcurrentHashMap = new ConcurrentHashMap<Long,TreeMap<Long, Long>>();
        }
        long currentMs = System.currentTimeMillis();
        long currentMinute = currentMs /60000;
        //ConcurrentHashMap<Long, TreeMap<Long, Long>> timeReginMap = TpCount.timeReginMap;
        TreeMap<Long, Long> longLongTreeMap = longTreeMapConcurrentHashMap.get(currentMinute);
        if (longLongTreeMap == null) {
            longLongTreeMap = new TreeMap<>(Comparator.naturalOrder());
        }
        Long callTimes = longLongTreeMap.get(spendTimems);//相同耗时的调用数
         if(callTimes == null){
            callTimes=1l;
        }else{
            callTimes +=1;
        }
        longLongTreeMap.put(spendTimems,callTimes);
        longTreeMapConcurrentHashMap.put(currentMinute,longLongTreeMap);
        timeReginMap.put(methodname,longTreeMapConcurrentHashMap);
    }

    public static void  reportTp(){
        long currentMs = System.currentTimeMillis();
        long currentMinute = currentMs / 60000;
        Iterator<Map.Entry<String, ConcurrentHashMap<Long, TreeMap<Long, Long>>>> iterator = timeReginMap.entrySet().iterator();
        while (iterator.hasNext()){
            Map.Entry<String, ConcurrentHashMap<Long, TreeMap<Long, Long>>> next = iterator.next();
            String methodname = next.getKey();
            ConcurrentHashMap<Long, TreeMap<Long, Long>> longLongTreeMap = next.getValue();
            if(longLongTreeMap !=null){
                doReportTp(methodname,longLongTreeMap.get(currentMinute));
            }
        }
    }


    public static void doReportTp(String methodname,TreeMap<Long, Long> treeMap){
        if(treeMap == null){
            return;
        }
        TreeMap<Long, Long> transMap = new TreeMap<>(Comparator.naturalOrder());
        AtomicReference<Long> idx= new AtomicReference<>(0l);
        treeMap.forEach((key,value)->{
            transMap.put(idx.get(),key);
            idx.updateAndGet(v -> v + value);
        });

        Long total=treeMap.values().stream().mapToLong(o->o).sum();
        Double idx90= Math.ceil((double)total*90/100);
        Double idx95= Math.ceil((double)total*95/100);
        Double idx99= Math.ceil((double)total*99/100);
        Map.Entry<Long, Long> idx90Entry = transMap.floorEntry(idx90.longValue());
        Map.Entry<Long, Long> idx95Entry = transMap.floorEntry(idx95.longValue());
        Map.Entry<Long, Long> idx99Entry = transMap.floorEntry(idx99.longValue());

        Long TP90=idx90Entry.getValue();
        Long TP95=idx95Entry.getValue();
        Long TP99=idx99Entry.getValue();

        System.out.println("方法-"+methodname+"的检测结果---"+"TP90:"+TP90+", TP95:"+TP95+", TP99:"+TP99);
    }

}
